package app.r_teenus.backend.dao;

import java.util.ArrayList;
import java.util.List;

import org.springframework.security.context.SecurityContextHolder;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import app.r_teenus.backend.model.Device;
import app.r_teenus.backend.model.Employee;
import app.r_teenus.backend.model.ServiceAction;
import app.r_teenus.backend.model.ServiceActionStatusType;
import app.r_teenus.backend.model.ServiceDevice;
import app.r_teenus.backend.model.ServiceDeviceStatusType;
import app.r_teenus.backend.model.ServiceOrder;
import app.r_teenus.backend.model.ServicePart;
import app.r_teenus.backend.model.ServiceRequest;
import app.r_teenus.backend.model.ServiceType;
import app.r_teenus.backend.model.SoStatusType;
import app.r_teenus.backend.model.UserAccount;


@Repository("orderDao")
@Transactional(readOnly = true)
public class ServiceOrderDaoImpl extends DefaultDaoImpl implements ServiceOrderDao {

	public List<ServiceOrder> findServiceOrders() {
		List<ServiceOrder> list = hibernateTemplate.loadAll(ServiceOrder.class);
		//for (ServiceOrder ser : list) {
			// getCustomer(ser);
//			DetachedCriteria criteria = DetachedCriteria.forClass(ServicePart.class);
//			criteria.createAlias("serviceOrder", "serviceOrder");
//			criteria.add(Restrictions.disjunction().add(Restrictions.eq("serviceOrder", ser)));
//			if (hibernateTemplate.findByCriteria(criteria).isEmpty()) {
//				ser.setCanRemove(true);
//				continue;
//			}
//			criteria = DetachedCriteria.forClass(ServiceAction.class);
//			criteria.createAlias("serviceOrder", "serviceOrder");
//			criteria.add(Restrictions.disjunction().add(Restrictions.eq("serviceOrder", ser)));
//			if (hibernateTemplate.findByCriteria(criteria).isEmpty()) {
//				ser.setCanRemove(true);
//				continue;
//			}
			
//			criteria = DetachedCriteria.forClass(ServiceDevice.class);
//			criteria.createAlias("serviceOrder", "serviceOrder");
//			criteria.add(Restrictions.disjunction().add(Restrictions.eq("serviceOrder", ser)));
//			if (hibernateTemplate.findByCriteria(criteria).isEmpty()) {
//				ser.setCanRemove(true);
//				continue;
//			}
//			criteria = DetachedCriteria.forClass(ServiceNote.class);
//			criteria.createAlias("serviceOrder", "serviceOrder");
//			criteria.add(Restrictions.disjunction().add(Restrictions.eq("serviceOrder", ser)));
//			if (hibernateTemplate.findByCriteria(criteria).isEmpty()) {
//				ser.setCanRemove(true);
//			}

			
		//}
		return list;
	}

	// public void getCustomer(ServiceOrder ser) {
	// if (ser.getCustomer().getSubject_type() == 1) {
	// ser.getCustomer().setPerson(hibernateTemplate.get(Person.class, ser.getCustomer().getSubject()));
	// } else if (ser.getCustomer().getSubject_type() == 2) {
	// ser.getCustomer().setEnterprise(hibernateTemplate.get(Enterprise.class, ser.getCustomer().getSubject()));
	// }
	// }

	public ServiceOrder findOrderById(Integer id) {
		ServiceOrder serviceOrder = hibernateTemplate.get(ServiceOrder.class, id);
		serviceOrder.getServiceDevice().setDeviceList(findDevices());
		serviceOrder.getServiceAction().setServiceTypeList(findServiceTypes());
		serviceOrder.setSoStatusTypeList(findSoStatusTypes());
		serviceOrder.getServiceAction().setServiceTypeId(serviceOrder.getServiceAction().getServiceType().getId());
//		DetachedCriteria criteria = DetachedCriteria.forClass(ServicePart.class);
//		criteria.createAlias("serviceOrder", "serviceOrder");
//		criteria.add(Restrictions.disjunction().add(Restrictions.eq("serviceOrder", serviceOrder)));
//		
//		serviceOrder.setServicePart((ServicePart) hibernateTemplate.findByCriteria(criteria).get(0));
//		
//		criteria = DetachedCriteria.forClass(ServiceAction.class);
//		criteria.createAlias("serviceOrder", "serviceOrder");
//		criteria.add(Restrictions.disjunction().add(Restrictions.eq("serviceOrder", serviceOrder)));
//		serviceOrder.setServiceAction((ServiceAction) hibernateTemplate.findByCriteria(criteria).get(0));
//
//		criteria = DetachedCriteria.forClass(ServiceDevice.class);
//		criteria.createAlias("serviceOrder", "serviceOrder");
//		criteria.add(Restrictions.disjunction().add(Restrictions.eq("serviceOrder", serviceOrder)));
//		
//		serviceOrder.setServiceDevice((ServiceDevice) hibernateTemplate.findByCriteria(criteria).get(0));
		
		return serviceOrder;
	}

	@Transactional(readOnly = false)
	public void deleteOrder(Integer id) {
		ServiceOrder ser = hibernateTemplate.get(ServiceOrder.class, id);
		hibernateTemplate.delete(ser);
	}

	public ServiceOrder createNewOrder(int serviceRequestId) {
		ServiceOrder serviceOrder = new ServiceOrder();
		serviceOrder.setId(-1);
		serviceOrder.setList(findServiceOrders());
		if(serviceRequestId != 0){
			serviceOrder.setId(0);
			serviceOrder.setServiceRequest(hibernateTemplate.get(ServiceRequest.class,serviceRequestId));
			serviceOrder.setServiceAction(new ServiceAction());
			serviceOrder.setSoStatusTypeList(findSoStatusTypes());
			serviceOrder.setSoStatusType(new SoStatusType());
			
			serviceOrder.setServicePart(new ServicePart());
			
			serviceOrder.getServiceAction().setServiceTypeList(findServiceTypes());
			
			serviceOrder.setServiceDevice(new ServiceDevice());
			serviceOrder.getServiceDevice().setDeviceList(findDevices());
			serviceOrder.getServiceDevice().setDevice(new Device());
			
		}
		
		return serviceOrder;
	}

	private List<Device> findDevices() {
		return hibernateTemplate.loadAll(Device.class);
	}

	private List<SoStatusType> findSoStatusTypes() {
		return hibernateTemplate.loadAll(SoStatusType.class);
	}

	private List<ServiceType> findServiceTypes() {
		return hibernateTemplate.loadAll(ServiceType.class);
	}

	@Transactional(readOnly = false)
	public ServiceOrder save(ServiceOrder serviceOrder) {
		
		if ( serviceOrder.getId() == 0)
			serviceOrder.setId(null);
		
		Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
		Employee employee = null;
		if (principal instanceof UserDetails) {

			String userName = ((UserDetails) principal).getUsername();
			String userPassword = ((UserDetails) principal).getPassword();
			Employee employeeTmp = new Employee();
			UserAccount userAccount = new UserAccount(userName, userPassword);
			employeeTmp.setUserAccount(new ArrayList<UserAccount>());
			employeeTmp.getUserAccount().add(userAccount);
			employee = (Employee) hibernateTemplate.findByExample(employeeTmp).get(0);
		}
		serviceOrder.setCreatedBy(employee);
		serviceOrder.getServiceAction().setServiceType(hibernateTemplate.get(ServiceType.class, serviceOrder.getServiceAction().getServiceTypeId()));
		serviceOrder.getServiceAction().setServiceActionStatusType(hibernateTemplate.get(ServiceActionStatusType.class, 1));
		
		double total = 0;
		total = serviceOrder.getServiceAction().getPrice()*serviceOrder.getServiceAction().getAmount();
		total+=serviceOrder.getServicePart().getCount()* serviceOrder.getServicePart().getPrice();
		serviceOrder.setPrice(total);
		hibernateTemplate.saveOrUpdate(serviceOrder);
		serviceOrder.getServiceAction().setServiceOrder(serviceOrder);
		
		serviceOrder.getServiceDevice().setServiceOrder(serviceOrder);
		serviceOrder.getServiceDevice().setServiceDeviceStatusType(hibernateTemplate.get(ServiceDeviceStatusType.class, 1));
		hibernateTemplate.saveOrUpdate(serviceOrder.getServiceDevice());
		serviceOrder.getServicePart().setServiceOrder(serviceOrder);
		serviceOrder.getServicePart().setServiceDevice(serviceOrder.getServiceDevice());
		hibernateTemplate.saveOrUpdate(serviceOrder.getServicePart());
		
		serviceOrder.getServiceAction().setServiceDevice(serviceOrder.getServiceDevice());
		hibernateTemplate.saveOrUpdate(serviceOrder.getServiceAction());
		return serviceOrder;
	}

}
